///////////////////////////////////////////////////////////////////////////////
///
/// Cylan Client Core
/// Copyright (C) Shenzhen Cylan Tech. Co., Ltd. 2012
///
/// \file       ICABScancode.h
/// \brief      ICAB键盘扫描码宏定义
///
///////////////////////////////////////////////////////////////////////////////
#ifndef ICAB_SCANCODE_H
#define ICAB_SCANCODE_H

/**
 * @typedef ICAB_ASCII_SCANCODE
 * @brief 键盘扫描码数据类型
 */
typedef struct ICAB_ASCII_SCANCODE
{
    int Scancode;
    int Modifier;
} ICAB_ASCII_SCANCODE;

#define icab_scancode_code(scancode)        ((uint8)(scancode & 0xff))
#define icab_scancode_extended(scancode)    (((scancode) & 0x100) ? 1 : 0)
#define mk_scancode(code, extended)         (((code) & 0xff) | ((extended) ? 0x100 : 0))

#define ICAB_SCANCODE_UNKNOWN       mk_scancode(0x00, 0)

#define ICAB_SCANCODE_ESCAPE        mk_scancode(0x01, 0) /* VK_ESCAPE */
#define ICAB_SCANCODE_KEY_1         mk_scancode(0x02, 0) /* VK_KEY_1 */
#define ICAB_SCANCODE_KEY_2         mk_scancode(0x03, 0) /* VK_KEY_2 */
#define ICAB_SCANCODE_KEY_3         mk_scancode(0x04, 0) /* VK_KEY_3 */
#define ICAB_SCANCODE_KEY_4         mk_scancode(0x05, 0) /* VK_KEY_4 */
#define ICAB_SCANCODE_KEY_5         mk_scancode(0x06, 0) /* VK_KEY_5 */
#define ICAB_SCANCODE_KEY_6         mk_scancode(0x07, 0) /* VK_KEY_6 */
#define ICAB_SCANCODE_KEY_7         mk_scancode(0x08, 0) /* VK_KEY_7 */
#define ICAB_SCANCODE_KEY_8         mk_scancode(0x09, 0) /* VK_KEY_8 */
#define ICAB_SCANCODE_KEY_9         mk_scancode(0x0A, 0) /* VK_KEY_9 */
#define ICAB_SCANCODE_KEY_0         mk_scancode(0x0B, 0) /* VK_KEY_0 */
#define ICAB_SCANCODE_OEM_MINUS     mk_scancode(0x0C, 0) /* VK_OEM_MINUS */
#define ICAB_SCANCODE_OEM_PLUS      mk_scancode(0x0D, 0) /* VK_OEM_PLUS */
#define ICAB_SCANCODE_BACKSPACE     mk_scancode(0x0E, 0) /* VK_BACK Backspace */
#define ICAB_SCANCODE_TAB           mk_scancode(0x0F, 0) /* VK_TAB */
#define ICAB_SCANCODE_KEY_Q         mk_scancode(0x10, 0) /* VK_KEY_Q */
#define ICAB_SCANCODE_KEY_W         mk_scancode(0x11, 0) /* VK_KEY_W */
#define ICAB_SCANCODE_KEY_E         mk_scancode(0x12, 0) /* VK_KEY_E */
#define ICAB_SCANCODE_KEY_R         mk_scancode(0x13, 0) /* VK_KEY_R */
#define ICAB_SCANCODE_KEY_T         mk_scancode(0x14, 0) /* VK_KEY_T */
#define ICAB_SCANCODE_KEY_Y         mk_scancode(0x15, 0) /* VK_KEY_Y */
#define ICAB_SCANCODE_KEY_U         mk_scancode(0x16, 0) /* VK_KEY_U */
#define ICAB_SCANCODE_KEY_I         mk_scancode(0x17, 0) /* VK_KEY_I */
#define ICAB_SCANCODE_KEY_O         mk_scancode(0x18, 0) /* VK_KEY_O */
#define ICAB_SCANCODE_KEY_P         mk_scancode(0x19, 0) /* VK_KEY_P */
#define ICAB_SCANCODE_OEM_4         mk_scancode(0x1A, 0) /* VK_OEM_4 '[' on US */
#define ICAB_SCANCODE_OEM_6         mk_scancode(0x1B, 0) /* VK_OEM_6 ']' on US */
#define ICAB_SCANCODE_RETURN        mk_scancode(0x1C, 0) /* VK_RETURN Normal Enter */
#define ICAB_SCANCODE_LCONTROL      mk_scancode(0x1D, 0) /* VK_LCONTROL */
#define ICAB_SCANCODE_KEY_A         mk_scancode(0x1E, 0) /* VK_KEY_A */
#define ICAB_SCANCODE_KEY_S         mk_scancode(0x1F, 0) /* VK_KEY_S */
#define ICAB_SCANCODE_KEY_D         mk_scancode(0x20, 0) /* VK_KEY_D */
#define ICAB_SCANCODE_KEY_F         mk_scancode(0x21, 0) /* VK_KEY_F */
#define ICAB_SCANCODE_KEY_G         mk_scancode(0x22, 0) /* VK_KEY_G */
#define ICAB_SCANCODE_KEY_H         mk_scancode(0x23, 0) /* VK_KEY_H */
#define ICAB_SCANCODE_KEY_J         mk_scancode(0x24, 0) /* VK_KEY_J */
#define ICAB_SCANCODE_KEY_K         mk_scancode(0x25, 0) /* VK_KEY_K */
#define ICAB_SCANCODE_KEY_L         mk_scancode(0x26, 0) /* VK_KEY_L */
#define ICAB_SCANCODE_OEM_1         mk_scancode(0x27, 0) /* VK_OEM_1 ';' on US */
#define ICAB_SCANCODE_OEM_7         mk_scancode(0x28, 0) /* VK_OEM_7 "'" on US */
#define ICAB_SCANCODE_OEM_3         mk_scancode(0x29, 0) /* VK_OEM_3 Top left, '`' on US, JP DBE_SBCSCHAR */
#define ICAB_SCANCODE_LSHIFT        mk_scancode(0x2A, 0) /* VK_LSHIFT */
#define ICAB_SCANCODE_OEM_5         mk_scancode(0x2B, 0) /* VK_OEM_5 Next to Enter, '\' on US */
#define ICAB_SCANCODE_KEY_Z         mk_scancode(0x2C, 0) /* VK_KEY_Z */
#define ICAB_SCANCODE_KEY_X         mk_scancode(0x2D, 0) /* VK_KEY_X */
#define ICAB_SCANCODE_KEY_C         mk_scancode(0x2E, 0) /* VK_KEY_C */
#define ICAB_SCANCODE_KEY_V         mk_scancode(0x2F, 0) /* VK_KEY_V */
#define ICAB_SCANCODE_KEY_B         mk_scancode(0x30, 0) /* VK_KEY_B */
#define ICAB_SCANCODE_KEY_N         mk_scancode(0x31, 0) /* VK_KEY_N */
#define ICAB_SCANCODE_KEY_M         mk_scancode(0x32, 0) /* VK_KEY_M */
#define ICAB_SCANCODE_OEM_COMMA     mk_scancode(0x33, 0) /* VK_OEM_COMMA */
#define ICAB_SCANCODE_OEM_PERIOD    mk_scancode(0x34, 0) /* VK_OEM_PERIOD */
#define ICAB_SCANCODE_OEM_2         mk_scancode(0x35, 0) /* VK_OEM_2 '/' on US */
#define ICAB_SCANCODE_RSHIFT        mk_scancode(0x36, 0) /* VK_RSHIFT */
#define ICAB_SCANCODE_MULTIPLY      mk_scancode(0x37, 0) /* VK_MULTIPLY Numerical */
#define ICAB_SCANCODE_LMENU         mk_scancode(0x38, 0) /* VK_LMENU Left 'Alt' key */
#define ICAB_SCANCODE_SPACE         mk_scancode(0x39, 0) /* VK_SPACE */
#define ICAB_SCANCODE_CAPSLOCK      mk_scancode(0x3A, 0) /* VK_CAPITAL 'Caps Lock', JP DBE_ALPHANUMERIC */
#define ICAB_SCANCODE_F1            mk_scancode(0x3B, 0) /* VK_F1 */
#define ICAB_SCANCODE_F2            mk_scancode(0x3C, 0) /* VK_F2 */
#define ICAB_SCANCODE_F3            mk_scancode(0x3D, 0) /* VK_F3 */
#define ICAB_SCANCODE_F4            mk_scancode(0x3E, 0) /* VK_F4 */
#define ICAB_SCANCODE_F5            mk_scancode(0x3F, 0) /* VK_F5 */
#define ICAB_SCANCODE_F6            mk_scancode(0x40, 0) /* VK_F6 */
#define ICAB_SCANCODE_F7            mk_scancode(0x41, 0) /* VK_F7 */
#define ICAB_SCANCODE_F8            mk_scancode(0x42, 0) /* VK_F8 */
#define ICAB_SCANCODE_F9            mk_scancode(0x43, 0) /* VK_F9 */
#define ICAB_SCANCODE_F10           mk_scancode(0x44, 0) /* VK_F10 */
#define ICAB_SCANCODE_NUMLOCK       mk_scancode(0x45, 0) /* VK_NUMLOCK */ /* Note: when this seems to appear in PKBDLLHOOKSTRUCT it means Pause which must be sent as Ctrl + NumLock */
#define ICAB_SCANCODE_SCROLLLOCK    mk_scancode(0x46, 0) /* VK_SCROLL 'Scroll Lock', JP OEM_SCROLL */
#define ICAB_SCANCODE_NUMPAD7       mk_scancode(0x47, 0) /* VK_NUMPAD7 */
#define ICAB_SCANCODE_NUMPAD8       mk_scancode(0x48, 0) /* VK_NUMPAD8 */
#define ICAB_SCANCODE_NUMPAD9       mk_scancode(0x49, 0) /* VK_NUMPAD9 */
#define ICAB_SCANCODE_SUBTRACT      mk_scancode(0x4A, 0) /* VK_SUBTRACT */
#define ICAB_SCANCODE_NUMPAD4       mk_scancode(0x4B, 0) /* VK_NUMPAD4 */
#define ICAB_SCANCODE_NUMPAD5       mk_scancode(0x4C, 0) /* VK_NUMPAD5 */
#define ICAB_SCANCODE_NUMPAD6       mk_scancode(0x4D, 0) /* VK_NUMPAD6 */
#define ICAB_SCANCODE_ADD           mk_scancode(0x4E, 0) /* VK_ADD */
#define ICAB_SCANCODE_NUMPAD1       mk_scancode(0x4F, 0) /* VK_NUMPAD1 */
#define ICAB_SCANCODE_NUMPAD2       mk_scancode(0x50, 0) /* VK_NUMPAD2 */
#define ICAB_SCANCODE_NUMPAD3       mk_scancode(0x51, 0) /* VK_NUMPAD3 */
#define ICAB_SCANCODE_NUMPAD0       mk_scancode(0x52, 0) /* VK_NUMPAD0 */
#define ICAB_SCANCODE_DECIMAL       mk_scancode(0x53, 0) /* VK_DECIMAL Numerical, '.' on US */
#define ICAB_SCANCODE_SYSREQ        mk_scancode(0x54, 0) /* Sys Req */
#define ICAB_SCANCODE_OEM_102       mk_scancode(0x56, 0) /* VK_OEM_102 Lower left '\' on US */
#define ICAB_SCANCODE_F11           mk_scancode(0x57, 0) /* VK_F11 */
#define ICAB_SCANCODE_F12           mk_scancode(0x58, 0) /* VK_F12 */
#define ICAB_SCANCODE_SLEEP         mk_scancode(0x5F, 0) /* VK_SLEEP OEM_8 on FR (undocumented?) */
#define ICAB_SCANCODE_ZOOM          mk_scancode(0x62, 0) /* VK_ZOOM (undocumented?) */
#define ICAB_SCANCODE_HELP          mk_scancode(0x63, 0) /* VK_HELP (undocumented?) */

#define ICAB_SCANCODE_F13           mk_scancode(0x64, 0) /* VK_F13 */ /* JP agree, should 0x7d according to ms894073 */
#define ICAB_SCANCODE_F14           mk_scancode(0x65, 0) /* VK_F14 */
#define ICAB_SCANCODE_F15           mk_scancode(0x66, 0) /* VK_F15 */
#define ICAB_SCANCODE_F16           mk_scancode(0x67, 0) /* VK_F16 */
#define ICAB_SCANCODE_F17           mk_scancode(0x68, 0) /* VK_F17 */
#define ICAB_SCANCODE_F18           mk_scancode(0x69, 0) /* VK_F18 */
#define ICAB_SCANCODE_F19           mk_scancode(0x6A, 0) /* VK_F19 */
#define ICAB_SCANCODE_F20           mk_scancode(0x6B, 0) /* VK_F20 */
#define ICAB_SCANCODE_F21           mk_scancode(0x6C, 0) /* VK_F21 */
#define ICAB_SCANCODE_F22           mk_scancode(0x6D, 0) /* VK_F22 */
#define ICAB_SCANCODE_F23           mk_scancode(0x6E, 0) /* VK_F23 */ /* JP agree */
#define ICAB_SCANCODE_F24           mk_scancode(0x6F, 0) /* VK_F24 */ /* 0x87 according to ms894073 */

#define ICAB_SCANCODE_HIRAGANA      mk_scancode(0x70, 0) /* JP DBE_HIRAGANA */
#define ICAB_SCANCODE_HANJA_KANJI   mk_scancode(0x71, 0) /* VK_HANJA / VK_KANJI (undocumented?) */
#define ICAB_SCANCODE_KANA_HANGUL   mk_scancode(0x72, 0) /* VK_KANA / VK_HANGUL (undocumented?) */
#define ICAB_SCANCODE_ABNT_C1       mk_scancode(0x73, 0) /* VK_ABNT_C1 JP OEM_102 */
#define ICAB_SCANCODE_F24_JP        mk_scancode(0x76, 0) /* JP F24 */
#define ICAB_SCANCODE_CONVERT_JP    mk_scancode(0x79, 0) /* JP CONVERT */
#define ICAB_SCANCODE_NONCONVERT_JP mk_scancode(0x7B, 0) /* JP NONCONVERT */
#define ICAB_SCANCODE_TAB_JP        mk_scancode(0x7C, 0) /* JP TAB */
#define ICAB_SCANCODE_BACKSLASH_JP  mk_scancode(0x7D, 0) /* JP OEM_5 ('\') */
#define ICAB_SCANCODE_ABNT_C2       mk_scancode(0x7E, 0) /* VK_ABNT_C2, JP */
#define ICAB_SCANCODE_ABNT_C2       mk_scancode(0x7E, 0) /* JP OEM_PA2 */

#define ICAB_SCANCODE_RETURN_KP     mk_scancode(0x1C, 1)  /* not ICAB_SCANCODE_RETURN Numerical Enter */
#define ICAB_SCANCODE_RCONTROL      mk_scancode(0x1D, 1)  /* VK_RCONTROL */
#define ICAB_SCANCODE_DIVIDE        mk_scancode(0x35, 1)  /* VK_DIVIDE Numerical */
#define ICAB_SCANCODE_PRINTSCREEN   mk_scancode(0x37, 1)  /* VK_EXECUTE/VK_PRINT/VK_SNAPSHOT Print Screen */
#define ICAB_SCANCODE_RMENU         mk_scancode(0x38, 1)  /* VK_RMENU Right 'Alt' / 'Alt Gr' */
#define ICAB_SCANCODE_PAUSE         mk_scancode(0x46, 1)  /* VK_PAUSE Pause / Break (Slightly special handling) */
#define ICAB_SCANCODE_HOME          mk_scancode(0x47, 1)  /* VK_HOME */
#define ICAB_SCANCODE_UP            mk_scancode(0x48, 1)  /* VK_UP */
#define ICAB_SCANCODE_PRIOR         mk_scancode(0x49, 1)  /* VK_PRIOR 'Page Up' */
#define ICAB_SCANCODE_LEFT          mk_scancode(0x4B, 1)  /* VK_LEFT */
#define ICAB_SCANCODE_RIGHT         mk_scancode(0x4D, 1)  /* VK_RIGHT */
#define ICAB_SCANCODE_END           mk_scancode(0x4F, 1)  /* VK_END */
#define ICAB_SCANCODE_DOWN          mk_scancode(0x50, 1)  /* VK_DOWN */
#define ICAB_SCANCODE_NEXT          mk_scancode(0x51, 1)  /* VK_NEXT 'Page Down' */
#define ICAB_SCANCODE_INSERT        mk_scancode(0x52, 1)  /* VK_INSERT */
#define ICAB_SCANCODE_DELETE        mk_scancode(0x53, 1)  /* VK_DELETE */
#define ICAB_SCANCODE_NULL          mk_scancode(0x54, 1)  /* <00> */
#define ICAB_SCANCODE_HELP2         mk_scancode(0x56, 1)  /* Help - documented, different from VK_HELP */
#define ICAB_SCANCODE_LWIN          mk_scancode(0x5B, 1)  /* VK_LWIN */
#define ICAB_SCANCODE_RWIN          mk_scancode(0x5C, 1)  /* VK_RWIN */
#define ICAB_SCANCODE_APPS          mk_scancode(0x5D, 1)  /* VK_APPS Application */
#define ICAB_SCANCODE_POWER_JP      mk_scancode(0x5E, 1)  /* JP POWER */
#define ICAB_SCANCODE_SLEEP_JP      mk_scancode(0x5F, 1)  /* JP SLEEP */

/* _not_ valid scancode, but this is what a windows PKBDLLHOOKSTRUCT for NumLock contains */
#define ICAB_SCANCODE_NUMLOCK_EXTENDED  mk_scancode(0x45, 1)  /* should be ICAB_SCANCODE_NUMLOCK */
#define ICAB_SCANCODE_RSHIFT_EXTENDED   mk_scancode(0x36, 1)  /* should be ICAB_SCANCODE_RSHIFT */

const ICAB_ASCII_SCANCODE *ICABScancodeForAscii(char Ascii);

#endif /* ICAB_SCANCODE_H */
